package com.hmall.common.utils;

import cn.hutool.core.lang.UUID;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.util.concurrent.ListenableFutureCallback;



@RequiredArgsConstructor
@Slf4j
public class RabbitMqHelper {

    private final RabbitTemplate rabbitTemplate;

    public void sendMessage(String exchange, String routingKey, Object msg){
        log.debug("交换机名称：{} ， routingKey：{} ， 信息：{}", exchange,routingKey,msg);
        rabbitTemplate.convertAndSend(exchange,routingKey,msg);
    }

    public void sendDelayMessage(String exchange, String routingKey, Object msg, int delay){
        log.debug("交换机名称：{} ， routingKey：{} ， 信息：{} ，延迟时间：{}ms", exchange,routingKey,msg,delay);
        rabbitTemplate.convertAndSend(
                exchange,
                routingKey,
                msg,
                message -> {
                    message.getMessageProperties().setDelay(delay);
                    return message;
        });
    }

    public void sendMessageWithConfirm(String exchange, String routingKey, Object msg, int maxRetries){
        CorrelationData cd = new CorrelationData(UUID.randomUUID().toString(true));
        cd.getFuture().addCallback(new ListenableFutureCallback<CorrelationData.Confirm>() {
            int retryCount;
            @Override
            public void onFailure(Throwable ex) {
                log.error("send message fail",ex);
            }
            @Override
            public void onSuccess(CorrelationData.Confirm result) {
                if(!result.isAck() && msg != null)
                {
                    log.error("消息发送失败！收到 nack，reason:{}",result.getReason());
                    log.error("已重试次数：{}",retryCount);
                    if(retryCount >= maxRetries)
                    {
                        log.error("最大重试次数耗尽，发送失败");
                        return;
                    }
                    CorrelationData cd = new CorrelationData(UUID.randomUUID().toString(true));
                    cd.getFuture().addCallback(this);
                    rabbitTemplate.convertAndSend(exchange, routingKey, msg, cd);
                    retryCount++;
                }
            }
        });
        rabbitTemplate.convertAndSend(exchange, routingKey, msg, cd);
    }
}